package conch.yaoms;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;

public class Bot extends Robot implements Runnable {

	private static HashMap<String, Integer> keyMap;

	private Random random = new Random();

	private MainFrame mFrame = null;

	private String configName = "default";

	public String getConfigName() {
		return configName;
	}

	public void setConfigName(String configName) {
		this.configName = configName;
	}

	static {
		keyMap = new HashMap<String, Integer>();

		keyMap.put("F1", KeyEvent.VK_F1);
		keyMap.put("F2", KeyEvent.VK_F2);
		keyMap.put("F3", KeyEvent.VK_F3);
		keyMap.put("F4", KeyEvent.VK_F4);
		keyMap.put("F5", KeyEvent.VK_F5);
		keyMap.put("F6", KeyEvent.VK_F6);
		keyMap.put("F7", KeyEvent.VK_F7);
		keyMap.put("F8", KeyEvent.VK_F8);
		keyMap.put("F9", KeyEvent.VK_F9);
		keyMap.put("F10", KeyEvent.VK_F10);

		keyMap.put("1", KeyEvent.VK_1);
		keyMap.put("2", KeyEvent.VK_2);
		keyMap.put("3", KeyEvent.VK_3);
		keyMap.put("4", KeyEvent.VK_4);
		keyMap.put("5", KeyEvent.VK_5);
		keyMap.put("6", KeyEvent.VK_6);
		keyMap.put("7", KeyEvent.VK_7);
		keyMap.put("8", KeyEvent.VK_8);
		keyMap.put("9", KeyEvent.VK_9);
		keyMap.put("0", KeyEvent.VK_0);

		keyMap.put("SPACE", KeyEvent.VK_SPACE);
	}

	/**
	 * 名称
	 */
	private String name = "波特";

	/**
	 * 问候语
	 */
	private String hello = "嗨，你好，我是《神魔大陆》自动打怪机器人，%s！请多多关照，如有问题联系： yms541@gmail.com";

	// 自动补蓝，自动补蓝
	/**
	 * 自动补红
	 */
	private boolean auto_cmp_hp = true;
	/**
	 * 补红阈值%
	 */
	private int hp_cmp_threshold = 50;
	/**
	 * 补红热键
	 */
	private String hp_cmp_key = "8";
	/**
	 * 自动补蓝
	 */
	private boolean auto_cmp_mp = true;
	/**
	 * 补蓝阈值%
	 */
	private int mp_cmp_threshold = 50;
	/**
	 * 补蓝热键
	 */
	private String mp_cmp_key = "9";

	// 自动使用技能
	/**
	 * 自动攻击
	 */
	private boolean auto_attack = true;

	public boolean isAuto_attack() {
		return auto_attack;
	}

	public void setAuto_attack(boolean autoAttack) {
		auto_attack = autoAttack;
	}

	/**
	 * 技能序列
	 */
	private ArrayList<RoleSkill> skills;
	// 自动拾取
	/**
	 * 自动拾取
	 */
	private boolean auto_fetch = true;

	/**
	 * 拾取快捷键
	 */
	private String auto_fetch_key = "F1";
	// 自动切换目标
	/**
	 * 自动切换目标
	 */
	private boolean auto_switch_target = true;

	/**
	 * 切换目标快键
	 */
	private String auto_switch_target_key = "TAB";

	/**
	 * 机器人运行
	 */
	private boolean going = false;

	public String getHello() {
		return hello;
	}

	public void setHello(String hello) {
		this.hello = hello;
	}

	public boolean isAuto_cmp_hp() {
		return auto_cmp_hp;
	}

	public void setAuto_cmp_hp(boolean autoCmpHp) {
		auto_cmp_hp = autoCmpHp;
	}

	public int getHp_cmp_threshold() {
		return hp_cmp_threshold;
	}

	public void setHp_cmp_threshold(int hpCmpThreshold) {
		hp_cmp_threshold = hpCmpThreshold;
	}

	public String getHp_cmp_key() {
		return hp_cmp_key;
	}

	public void setHp_cmp_key(String hpCmpKey) {
		hp_cmp_key = hpCmpKey;
	}

	public boolean isAuto_cmp_mp() {
		return auto_cmp_mp;
	}

	public void setAuto_cmp_mp(boolean autoCmpMp) {
		auto_cmp_mp = autoCmpMp;
	}

	public int getMp_cmp_threshold() {
		return mp_cmp_threshold;
	}

	public void setMp_cmp_threshold(int mpCmpThreshold) {
		mp_cmp_threshold = mpCmpThreshold;
	}

	public String getMp_cmp_key() {
		return mp_cmp_key;
	}

	public void setMp_cmp_key(String mpCmpKey) {
		mp_cmp_key = mpCmpKey;
	}

	public ArrayList<RoleSkill> getSkills() {
		return skills;
	}

	public void setSkills(ArrayList<RoleSkill> skills) {
		this.skills = skills;
	}

	public boolean isAuto_fetch() {
		return auto_fetch;
	}

	public void setAuto_fetch(boolean autoFetch) {
		auto_fetch = autoFetch;
	}

	public String getAuto_fetch_key() {
		return auto_fetch_key;
	}

	public void setAuto_fetch_key(String autoFetchKey) {
		auto_fetch_key = autoFetchKey;
	}

	public boolean isAuto_switch_target() {
		return auto_switch_target;
	}

	public void setAuto_switch_target(boolean autoSwitchTarget) {
		auto_switch_target = autoSwitchTarget;
	}

	public String getAuto_switch_target_key() {
		return auto_switch_target_key;
	}

	public void setAuto_switch_target_key(String autoSwitchTargetKey) {
		auto_switch_target_key = autoSwitchTargetKey;
	}

	public boolean isGoing() {
		return going;
	}

	public void setGoing(boolean going) {
		this.going = going;
	}

	public void say(String what) {
		if (mFrame != null) {
			mFrame.append(now() + name + ":" + what + "\n");
		} else {
			System.out.println(now() + " " + name + ": " + what);
		}
	}

	private SimpleDateFormat dateFormat = new SimpleDateFormat("mm:ss.SSS");

	private String now() {
		return dateFormat.format(new Date());
	}

	public Bot() throws AWTException {
		super();
	}

	public Bot(BotConfig config) throws AWTException {
		super();

		initConfig(config);
	}

	public Bot(BotConfig config, MainFrame myFrame) throws AWTException {
		super();

		this.mFrame = myFrame;

		initConfig(config);
	}

	private void initConfig(BotConfig config) {

		Bot bot = this;

		bot.setConfigName(config.getString("description"));

		bot.setAuto_cmp_hp(config.getBoolean("Auto_cmp_hp"));
		bot.setHp_cmp_threshold(config.getInt("Hp_cmp_threshold"));
		bot.setHp_cmp_key(config.getString("Hp_cmp_key"));
		bot.setAuto_cmp_mp(config.getBoolean("Auto_cmp_mp"));
		bot.setMp_cmp_threshold(config.getInt("Mp_cmp_threshold"));
		bot.setMp_cmp_key(config.getString("Mp_cmp_key"));

		bot.setAuto_attack(config.getBoolean("Auto_attack"));

		ArrayList<RoleSkill> roleSkills = new ArrayList<RoleSkill>();

		RoleSkill skill;
		for (int i = 1; i < 17; i++) {

			skill = new RoleSkill();
			skill.setName(config.getString("skill_" + i + ".name", null));
			skill.setLoop(config.getBoolean("skill_" + i + ".loop", false));
			skill.setHotKey(config.getString("skill_" + i + ".key", null));
			skill.setCoolDown(config.getInt("skill_" + i + ".coolDown", 0));

			roleSkills.add(skill);
		}

		bot.setSkills(roleSkills);

		bot.setAuto_fetch(config.getBoolean("Auto_fetch"));
		bot.setAuto_fetch_key(config.getString("Auto_fetch_key"));

		bot.setAuto_switch_target(config.getBoolean("Auto_switch_target"));
		bot.setAuto_switch_target_key(config
				.getString("Auto_switch_target_key"));
	}

	public void go() {
		if (!isGoing()) {
			going = true;
			new Thread(this).start();
		}
	}

	@Override
	public void run() {
		try {
			say("开始自动操作");

			// 切换窗口 Alt+Tab
			keyPress(KeyEvent.VK_ALT);
			keyPress(KeyEvent.VK_TAB);
			keyRelease(KeyEvent.VK_TAB);
			keyRelease(KeyEvent.VK_ALT);

			Thread.sleep(10);

			// 使人物跳跃一次 :P
			pressKey("SPACE");

			Thread.sleep(200);

			while (going) {
				// 是否有提示
				// 报警，并停止外挂

				// 是否需要补血
				// 是，补血
				// 是否需要补蓝
				// 是，补蓝
				// 是否有目标
				// 否，自动拾取
				// 是否有目标
				// 否，切换目标
				//

				// 自动攻击
				if (auto_attack) {
					for (RoleSkill roleSkill : skills) {
						// 如果技能有效并已经冷却
						if (roleSkill.getName() != null
								&& roleSkill.getCoolDown() * 1000L < System
										.currentTimeMillis()
										- roleSkill.getLastUse()) {

							say("按下『" + roleSkill.getHotKey() + "』施展『"
									+ roleSkill.getName() + "』");

							// 按下相应热键
							pressKey(roleSkill.getHotKey());

							// 重置冷却计时器
							roleSkill.setLastUse(System.currentTimeMillis());

							// 休眠一定时间再使用下一个技能
							Thread.sleep(10 + random.nextInt(30));
						}
					}
				}

				// 休眠一段时间在进行下一轮按键操作
				Thread.sleep(30);
			}

			say("停止自动操作");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void pressKey(String hotKey) throws InterruptedException {

		keyPress(map(hotKey));
		Thread.sleep(100 + random.nextInt(50));
		keyRelease(map(hotKey));
	}

	private int map(String hotKey) {
		return keyMap.get(hotKey);
	}

	public void look() {
		say(String.format(hello, name));
		say("当前配置：" + getConfigName());
		say(" - 自动补血：『" + isAuto_cmp_hp() + "』");
		say(" - 补血阈值：『" + getHp_cmp_threshold() + "%』");
		say(" - 补血热键：『" + getHp_cmp_key() + "』");
		say(" -");
		say(" - 自动补蓝：『" + isAuto_cmp_mp() + "』");
		say(" - 补蓝阈值：『" + getMp_cmp_threshold() + "%』");
		say(" - 补蓝热键：『" + getMp_cmp_key() + "』");
		say(" -");
		say(" - 自动攻击：『" + isAuto_attack() + "』");
		for (RoleSkill roleSkill : skills) {
			if (roleSkill.getName() != null) {
				say(roleSkill.getName() + ":" + "热键『" + roleSkill.getHotKey()
						+ "』冷却『" + roleSkill.getCoolDown() + "秒』");
			}
		}
		say(" -");
		say(" - 自动拾取：『" + isAuto_fetch() + "』");
		say(" - 拾取热键：『" + getAuto_fetch_key() + "』");
		say(" -");
		say(" - 自动切换：『" + isAuto_switch_target() + "』");
		say(" - 切换热键：『" + getAuto_switch_target_key() + "』");
	}

	public void pause() {
		if (isGoing()) {
			setGoing(false);
		}
	}
}
